#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Copyright © 启明星辰 版权所有
# @Time    : 2023/11/7 14:48
# @Author  : 胡浩浩
# @File    : count_data_manage.py
# @IDE     : PyCharm
# @description : 数据大盘展示
import json
import time

import jmespath
import requests
from pywebio.output import *
from pyecharts.charts import Bar
from pyecharts.commons.utils import JsCode
from pywebio.output import put_html
from pyecharts import options as opts
from pyecharts.charts import Pie
from pywebio.pin import put_select, pin_wait_change, pin

from apps.commons.comms import IPADDRESS
from apps.src.menus import show_menus
from config import APIPORT


def show_api_rate_chart(chart_item):
    """
        这是一个公共组件
        这个组件显示接口覆盖率的数据
    """
    c = (
        Pie()
        .add(
            f"{chart_item[1]}接口总数:{len(chart_item[3])}",
            [list(z) for z in
             zip(["已覆盖", "未覆盖"], [chart_item[2], round(100 - chart_item[2], 2)])],
            center=["45%", "50%"],
            radius=[70, 100],
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="接口覆盖率"),
            legend_opts=opts.LegendOpts(
                type_="scroll", pos_top="10%", pos_left="90%", orient="vertical"
            ),
        )
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}%"))

    )
    c.width = "100%"
    c.height = "250px"
    return put_row([
        put_html(c.render_notebook()),
        None
    ], size="90%", scope="api_chart_list")


def show_api_model_chart(chart_item, all_api_dict):
    # print("chart_item-----",chart_item)
    # print("chart_item-----",all_api_dict)
    c = (
        Pie()
        .add(
            f"{chart_item[1]}",
            [
                list(z)
                for z in zip(
                all_api_dict[chart_item[0]][chart_item[1]].keys(),
                [len(item) for item in all_api_dict[chart_item[0]][chart_item[1]].values()],
            )
            ],
            radius=[0, 150],
            center=["45%", "50%"],
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="全接口统计"),
            legend_opts=opts.LegendOpts(type_="scroll", pos_left="85%", orient="vertical", item_height=10,
                                        item_width=15),
        )
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))

    )

    c.width = "100%"
    return put_row([
        put_html(c.render_notebook()),
        put_button("全部接口详情", onclick=lambda: show_api_list(chart_item[0], chart_item[1], all_api_dict, "全部"),
                   color="danger", small=True)
    ], size="90%", scope="api_chart_list")


def show_top_cover_rate(product_version, data_dict):
    """
        统计各模块接口覆盖率top20的情况
    """
    sorted_dict = dict(sorted(data_dict.items(), key=lambda x: x[1], reverse=False))
    c = (
        Bar()
        .add_xaxis(list(sorted_dict.keys())[:20])
        .add_yaxis("接口覆盖率", list(sorted_dict.values())[:20], category_gap="60%")
        .set_series_opts(
            itemstyle_opts={
                "normal": {
                    "color": JsCode(
                        """new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                    offset: 0,
                    color: 'rgba(0, 244, 255, 1)'
                }, {
                    offset: 1,
                    color: 'rgba(0, 77, 167, 1)'
                }], false)"""
                    ),
                    "barBorderRadius": [30, 30, 30, 30],
                    "shadowColor": "rgb(0, 160, 221)",
                }
            }
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="覆盖率倒数排行榜top20"),
            xaxis_opts=opts.AxisOpts(axislabel_opts={"rotate": 35})
        )


    )

    c.width = "100%"

    return put_html(c.render_notebook(), scope="api_chart_list")


def show_case_api_model_chart(chart_item, case_api_dict, all_api_dict, product_version, product_name,
                              no_cover_all_api_dict):
    """
        按模块显示接口分布情况
    """
    print(f"{time.strftime('%Y-%m-%d %H:%M:%S：')}", "我正在调试中")

    data_dict = {}
    for key, value in dict(all_api_dict[product_name][product_version]).items():
        if len(value) > 0:
            data_dict[key] = round(
                len(set(case_api_dict[product_name][product_version][key])) / len(
                    set(all_api_dict[product_name][product_version][key])) * 100, 2)
    c = (
        Pie()
        .add(
            f"{chart_item[1]}",
            [
                list(z)
                for z in zip(
                data_dict.keys(),
                list(data_dict.values()),
            )
            ],
            radius=[0, 100],
            center=["35%", "50%"],
        )

        .set_global_opts(
            title_opts=opts.TitleOpts(title="各模块覆盖率"),
            legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%", orient="vertical", item_height=10,
                                        item_width=15),
        )
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}%"))

    )

    c.width = "100%"


    return put_row([
        put_html(c.render_notebook()),
        None,
        put_button("未覆盖详情",
                   onclick=lambda: show_api_list(chart_item[0], chart_item[1], no_cover_all_api_dict, "未覆盖"),

                   color="danger",small=True),
        None,
        show_top_cover_rate(chart_item[1], data_dict)
    ], size="48% 1% 2% 2%", scope="api_chart_list")


def show_api_list(product_name, product_version, data_dict: dict, title):
    print(f"{time.strftime('%Y-%m-%d %H:%M:%S：')}我正在调试中")
    # print(data_dict)
    show_data = []
    data_list = [
        [
            put_html(f'<h4 style="width:600px">模块分组({len(data_dict[product_name][product_version])})</h4>')
        ]
    ]
    for k, v in data_dict[product_name][product_version].items():
        # print(k)
        # print(v)
        data_list.append([put_collapse(f"{k}({len(v)})", put_text('\n'.join(v)))])
    data = {
        "title": f"{product_version}",
        "content": [
            put_table(
                data_list
            )
        ]
    }
    show_data.append(data)

    return popup(f'{title}接口详情', [
        put_scrollable(put_tabs(show_data), 600),
        put_buttons(['关闭'], onclick=lambda _: close_popup(), small=True)
    ], size="large")


def show_data_market(result_list, case_api_dict, all_api_dict, no_cover_all_api_dict):
    """
        接口覆盖率
    """
    # 进行接口覆盖率统计
    # 先拿到所有的禅道中的用例
    # 再拿到所有swagger中的用例
    # 进行覆盖率计算，算出不同产品不同版本的接口覆盖率
    # print(result_list)

    with use_scope("data_list", clear=True):
        put_scope("api_header")
        put_scope("api_chart_list")
    product_list = [p[1] for p in result_list]
    product_list=reversed(product_list)
    print(f"{time.strftime('%Y-%m-%d %H:%M:%S：')}", product_list)
    put_row([
        None,
        put_text("当前产品及版本"),
        put_select("product", product_list)
    ], size="60% 8%", scope="api_header")
    product_version = pin.product
    print(f"{time.strftime('%Y-%m-%d %H:%M:%S：')}", product_version)
    product_item = jmespath.search(f"@[?@[1]==`{product_version}`]|[0]", result_list)
    # print(json.dumps(product_item, ensure_ascii=False))
    show_api_rate_chart(product_item)
    print(f"{time.strftime('%Y-%m-%d %H:%M:%S：')}我正在调试中-----")
    # print(product_item)

    put_html("<hr>", scope="api_chart_list")
    show_case_api_model_chart(product_item, case_api_dict, all_api_dict, product_version, product_item[0],
                              no_cover_all_api_dict)
    put_html("<hr>", scope="api_chart_list")
    show_api_model_chart(product_item, all_api_dict)


def show_html_data_market():
    """
    数据大盘
    """

    result_list = requests.get(f"http://{IPADDRESS}:{APIPORT}/count_data").json()
    groups_dict_list = requests.get(f"http://{IPADDRESS}:{APIPORT}/groups").json()
    case_api_dict = {}
    all_api_dict = {}
    no_cover_all_api_dict = {}

    for result in result_list:
        if not all_api_dict.get(result[0]):
            all_api_dict[result[0]] = {}
        if not no_cover_all_api_dict.get(result[0]):
            no_cover_all_api_dict[result[0]] = {}
        if not case_api_dict.get(result[0]):
            case_api_dict[result[0]] = {}

        if not all_api_dict.get(result[0]).get(result[1]):
            all_api_dict[result[0]][result[1]] = {"未分组接口":[]}
        if not no_cover_all_api_dict[result[0]].get(result[1]):
            no_cover_all_api_dict[result[0]][result[1]] = {"未分组接口":[]}
        if not case_api_dict[result[0]].get(result[1]):
            case_api_dict[result[0]][result[1]] = {"未分组接口":[]}


        current_model=jmespath.search(f'@[?@[0]==`"{result[1]}"`]|[0][1]', groups_dict_list) if jmespath.search(f'@[?@[0]==`"{result[1]}"`]|[0][1]', groups_dict_list) else jmespath.search(f'@[?@[0]==`"{result[0]}"`]|[0][1]', groups_dict_list)
        print(json.dumps(groups_dict_list,ensure_ascii=False))
        print("胡浩浩",current_model)
        model_dict = json.loads(current_model)
        # print("今天调试的参数",result[0])
        # print("今天调试的参数",result[1])
        # print(json.dumps(groups_dict_list,ensure_ascii=False))
        # print(model_dict)
        for key in model_dict.keys():
            all_api_dict[result[0]][result[1]][key] = []
            no_cover_all_api_dict[result[0]][result[1]][key] = []
            case_api_dict[result[0]][result[1]][key] = []
        # print("case_api_dict---------", json.dumps(case_api_dict, ensure_ascii=False))
        # print("111111111111",json.dumps(all_api_dict,ensure_ascii=False))
        # 初始化swagger接口全集数据-------------
        result[3].sort()
        # model_dict = jmespath.search(f"@[?@[0]==`{result[0]}`]|[0][1]", groups_dict_list)
        for path in result[3]:
            flag = False
            for model_key, model_value in model_dict.items():
                for v in model_value:
                    if not flag and path.startswith(v):
                        # print("我在")
                        all_api_dict[result[0]][result[1]][model_key].append(path)
                        flag = True
                        break
            if not flag:
                all_api_dict[result[0]][result[1]]["未分组接口"].append(path)

        # 初始化未覆盖接口数据-------------------
        difference = list(set(result[3]) - set(result[4]))

        difference.sort()
        for path in difference:
            flag = False
            for model_key, model_value in model_dict.items():
                for v in model_value:
                    if not flag and path.startswith(v):
                        no_cover_all_api_dict[result[0]][result[1]][model_key].append(path)
                        flag = True
                        break
            if not flag:
                no_cover_all_api_dict[result[0]][result[1]]["未分组接口"].append(path)
        result[4].sort()
        for path in result[4]:
            flag = False
            for model_key, model_value in model_dict.items():
                for v in model_value:
                    if not flag and path.startswith(v):
                        # print("我在")
                        case_api_dict[result[0]][result[1]][model_key].append(path)
                        flag = True
                        break
            if not flag:
                case_api_dict[result[0]][result[1]]["未分组接口"].append(path)
    # print("2222222222222",json.dumps(all_api_dict, ensure_ascii=False))
    # print("未被覆盖的接口", json.dumps(no_cover_all_api_dict,ensure_ascii=False))
    for key, value in no_cover_all_api_dict.items():
        for k, v in dict(value).items():
            for g, l in dict(v).items():
                if not l:
                    del no_cover_all_api_dict[key][k][g]
    # print("未被覆盖的接口", no_cover_all_api_dict)
    for key, value in all_api_dict.items():
        # print(key)
        # print(value)
        for k, v in dict(value).items():
            for g, l in dict(v).items():
                if not l:
                    del all_api_dict[key][k][g]

    show_menus()
    show_data_market(result_list, case_api_dict, all_api_dict, no_cover_all_api_dict)
    put_html("<hr>", scope="data_list")

    while True:
        # 检测产品，如果产品发生了变更，则页面中的数据都切换成对应产品的数据
        # 接口覆盖率
        # 接口统计
        # 未覆盖接口统计
        # yml用例中的接口统计
        changed = pin_wait_change("product")
        # print(changed)
        if changed:
            with use_scope("api_chart_list", clear=True):
                # put_text(f"我被执行了{changed['value']}")
                # 展示在这里定义新的统计图
                product_item = jmespath.search(f"@[?@[1]==`{changed['value']}`]|[0]", result_list)
                # print(product_item)
                show_api_rate_chart(product_item)
                put_html("<hr>", scope="api_chart_list")
                show_case_api_model_chart(product_item, case_api_dict, all_api_dict, changed['value'], product_item[0],
                                          no_cover_all_api_dict)
                put_html("<hr>", scope="api_chart_list")
                show_api_model_chart(product_item, all_api_dict)
        continue
